function main() {
    Java.perform(function () {
        Java.use("com.a.sample.loopcrypto.Decode").a.overload("[B", "long").implementation = function (b, i) {
            var result = this.a(b, i);
            console.log(Java.use("java.lang.String").$new(result));
            return result;
        };

        hook_init()
        // hook_libart()
        // inline_hook()
    });
}

function hook_init() {
    // 寻找linker
    var linker
    if (Process.pointerSize == 4) {
        console.log("linker")
        linker = Process.findModuleByName("linker");
    }else if (Process.pointerSize == 8) {
         console.log("linker64")
        linker = Process.findModuleByName("linker64");
    }
    var call_function_addr = null;
    // 遍历linker的符号
    var symbols = linker.enumerateSymbols();
    for (var i = 0; i < symbols.length; i++) {
        // 取到名称
        var name = symbols[i].name;
        // 如果名称是call_function，则得到该地址并返回
        if (name.indexOf("call_function") >= 0) {
            call_function_addr = symbols[i].address;
            break;
        }
    }
    console.log("call_function_addr->", call_function_addr);
    // 来附加call_function函数
    if (call_function_addr) {
        Interceptor.attach(call_function_addr, {
            onEnter: function (args) {
                // 进入函数的时候判断要执行的函数地址末尾是否是3dd
                if (String(args[1]).indexOf("3dd") >= 0) {
                    console.log("found");
                    // 如果根据函数地址找到了初始化函数，则对其进行hook，置空处理
                    Interceptor.replace(
                        args[1],
                        new NativeCallback(
                            function (s, addr, rp) {
                                console.log("destory")
                            },
                            "int",
                            []
                        )
                    );
                }
            },
            onLeave: function (retval) {

            }
        })
    }

}


function hook_libart() {
    var module_libart = Process.findModuleByName("libart.so");
    var symbols = module_libart.enumerateSymbols();     //枚举模块的符号

    var addr_GetStringUTFChars = null;
    var addr_FindClass = null;
    var addr_GetStaticFieldID = null;
    var addr_SetStaticIntField = null;
    var addr_RegisterNatives = null;

    for (var i = 0; i < symbols.length; i++) {
        var name = symbols[i].name;
        if (name.indexOf("art") >= 0) {//动态获取各个函数的地址
            if ((name.indexOf("CheckJNI") == -1) && (name.indexOf("JNI") >= 0)) {
                if (name.indexOf("GetStringUTFChars") >= 0) {
                    // console.log(name);
                    addr_GetStringUTFChars = symbols[i].address;
                } else if (name.indexOf("FindClass") >= 0) {
                    // console.log(name);
                    addr_FindClass = symbols[i].address;
                } else if (name.indexOf("GetStaticFieldID") >= 0) {
                    // console.log(name);
                    addr_GetStaticFieldID = symbols[i].address;
                } else if (name.indexOf("SetStaticIntField") >= 0) {
                    // console.log(name);
                    addr_SetStaticIntField = symbols[i].address;
                } else if (name.indexOf("RegisterNatives") >= 0) {
                    addr_RegisterNatives = symbols[i].address;
                    console.log(name, addr_RegisterNatives);
                }
            }
        }
    }

    if (addr_RegisterNatives) {
        Interceptor.attach(addr_RegisterNatives, {
            onEnter: function (args) {
                console.log(">>>>>>")
                console.log("addr_RegisterNatives:", hexdump(args[2]));    //打印第三个参数，也就是java和native映射的数组首地址
                console.log("addr_RegisterNatives name:", ptr(args[2]).readPointer().readCString())//java层函数名称
                console.log("addr_RegisterNatives sig:", ptr(args[2]).add(Process.pointerSize).readPointer().readCString());//函数参数
                console.log("addr_RegisterNatives addr:", ptr(args[2]).add(Process.pointerSize+Process.pointerSize));//native函数入口地址
            }, onLeave: function (retval) {
                console.log(11111)
            }
        });
    }
}


//刚注入的时候这个so还没加载，需要hook dlopen
function inline_hook() {
    var base_hello_jni = Module.findBaseAddress("libcheck.so");
    console.log("base_hello_jni:", base_hello_jni);
    if (base_hello_jni) {
        //inline hook
        var addr = base_hello_jni.add(0x8916).add(0x1);//指令执行的地址，不是变量所在的栈或堆
        Interceptor.attach(addr, {
            onEnter: function (args) {
                console.log("addr x13:", this.context);//注意这里是怎么得到寄存器值的
            }, onLeave: function (retval) {
            }
        });
    }
}

//8.0以下所有的so加载都通过dlopen
function hook_dlopen() {
    var dlopen = Module.findExportByName(null, "dlopen");
    Interceptor.attach(dlopen, {
        onEnter: function (args) {
            this.call_hook = false;
            var so_name = ptr(args[0]).readCString();
            if (so_name.indexOf("libcheck.so") >= 0) {
                console.log("dlopen:", ptr(args[0]).readCString());
                this.call_hook = true;//dlopen函数找到了
            }

        }, onLeave: function (retval) {
            if (this.call_hook) {//dlopen函数找到了就hook so
                inline_hook();
            }
        }
    });
    // 高版本Android系统使用android_dlopen_ext
    var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
    Interceptor.attach(android_dlopen_ext, {
        onEnter: function (args) {
            this.call_hook = false;
            var so_name = ptr(args[0]).readCString();
            if (so_name.indexOf("libcheck.so") >= 0) {
                console.log("android_dlopen_ext:", ptr(args[0]).readCString());
                this.call_hook = true;
            }

        }, onLeave: function (retval) {
            if (this.call_hook) {
                inline_hook();
            }
        }
    });
}

setImmediate(main);
